package se.jagvetintedu;

// A Pythagorean triplet is a set of three natural numbers, a  b  c, for which,

// a^2 + b^2 = c^2
// For example, 3^2 + 4^2 = 9 + 16 = 25 = 5^2.
//
// There exists exactly one Pythagorean triplet for which a + b + c = 1000.
// Find the product abc.

public class Problem9 {
	
	private class Triplet {
		private Integer[] triplet;
		
		public Triplet(int a, int b, int c) {
			triplet = new Integer[3];
			
			triplet[0] = a;
			triplet[1] = b;
			triplet[2] = c;
			
//			System.out.println("Triplet: " + toString() + " = " + sum());
		}
		
		public Integer sum() {
			Integer sum = 0;
			for (int i : triplet) {
				sum += i;
			}
//			System.out.println("Sum of: " + toString() + " = " + sum);
			return sum;
		}
		
		public Integer product() {
			Integer product = 1;
			for (int i : triplet) {
				product *= i;
			}
			System.out.println("Product of: " + toString() + " = " + product);
			return product;
		}
		
		public String toString() {
			return new String("[" + triplet[0] + ", " + triplet[1] + ", " + triplet[2] + "]");
		}
	}
	
	private class PythagoreanTriplets {
		private Integer k;
		private Triplet triplet;
		private Integer m;
		private Integer n;
		
		public PythagoreanTriplets() {
			k = 9; // Set k to first possible odd square number;
			
			m = 2;
			n = 1;
			
		}
		
		private void findNextOddSquare() {
			while (true) {
				k += 2;
				double root = Math.sqrt(k);
				if (root == Math.round(root)) {
					return;
				}
			}
		}
		
		private double sumOdd(double n) {
			double sum = 0;
			int v = 1;
			while (n > 0) {
				sum += v;
				v += 2;
				n--;
			}
			
			return sum;
		}
		
		public void calculateNextTripletFibonacci() {
			Double a = Math.sqrt(k);
			Double n = ((a*a)+1)/2;
			Double b = Math.sqrt(sumOdd(n-1));
			Double c = Math.sqrt(sumOdd(n));
			
			System.out.println("Triplet: [" + a + ", " + b + ", " + c + "]");
			
			triplet = new Triplet(a.intValue(), b.intValue(), c.intValue());
			
			findNextOddSquare();
			System.out.println("Next odd Square = " + k);
		}
		
		public void calculateNextTripletEuclid(Integer sum) {
			Double a = Math.pow(m, 2)- Math.pow(n, 2);
			Integer b = 2 * m * n;
			Double c = Math.pow(m, 2)+ Math.pow(n, 2);
			
			triplet = new Triplet(a.intValue(), b, c.intValue());
			System.out.println("Triplet: [" + m + ", " + n + "]->" + triplet.toString() + "= " + triplet.sum());
			
			findNextmn(sum);
		}
		
		private void findNextmn(Integer sum) {
			if (triplet.sum() > sum) {
				n++;
				m = n + 1;;
			} 
			else {
				m++;
			}
			if (m > sum) {
				System.out.println("ERROR");
			}
				
		}
		public Triplet getTriplet() {
			return triplet;
		}
	}
	
	PythagoreanTriplets pyth;
	
	public Problem9() {
		pyth = new PythagoreanTriplets();
	}
	
	Triplet getTriplet(Integer sum) {

		Triplet triplet;
		do {
			pyth.calculateNextTripletEuclid(sum);
		
			triplet = pyth.getTriplet();
		} while(triplet.sum().compareTo(sum)!= 0);
			
		return triplet;
	}

	public static void main(String args[])
	{
		System.out.println("Project Euler, problem 9");
		
		Problem9 solution = new Problem9();

		Triplet triplet = solution.getTriplet(1000);
		System.out.println("The product abc of the Pythagorean tripled where a+b+c=1000: " + triplet.product());
	}
}
